debug = {}; /* This object is here to bring whatever you want out into the global space to look at.
	There are probably more elegant ways to do it, but meh.
*/


/*
	Creates an alert element with the message and specified type.
	
	@messge - The message you'd like to display in the alert
	@type - error, info, success
	returns - HTML element
*/
function createAlert(message,type){

	var alertMessage = $(document.createElement('span'))
						.attr("id","loginAlertMessage")
						.html(message);
						
	var alertClose = $(document.createElement('a'))
						.addClass("close")
						.attr('data-dismiss','alert')
						.attr("href","#")
						.append("&times;");
						
	var alertContainer = $(document.createElement('div'))
							.addClass("span4 offset4 alert alert-"+type);

							
	alertContainer
		.append(alertMessage)
		.append(alertClose);
	
	return alertContainer;
							
/*
<div id="displayAlert" class="span4 offset4 alert">
	<span id="loginAlertMessage"></span>
	<a class="close" data-dismiss="alert" href="#">&times;</a>
</div>
*/

}

/*
	Function escapeData
		Removes escape characters from data so that they display properly
*/
function escapeData(inputData){
	return inputData.replace(/\\./g, '$1');
}


/*
	Function showLoadingIndicator
		Displays the "loading" indicator. Useful for indicating to the user that something is happening.
*/
function showLoadingIndicator(){
	$("div.popover#loading").fadeIn();
}

/*
	Function hideLoadingIndicator
		Displays the "loading" indicator. Useful for indicating to the user that something is happening.
*/
function hideLoadingIndicator(){
	$("div.popover#loading").fadeOut();
}


/*
	Function showSection
		Displays the related section on the page when a tab has been clicked. The click binding is done in the index document
		
		object @eventOb - The event object generated by the click. Passed by the anonymous function in the click bind.
*/

function showSection(eventOb){
	$(".section").hide();
	$("#"+$(eventOb.target).closest("a.btn").attr("data-section")).show();
}

function showSection2(eventOb){
	$(".section").hide();
	var navElement = $("#"+eventOb.target.id);
	$("ul.nav li.active").removeClass("active");
	
	$(navElement).closest("li").addClass("active");
	$("#"+$(eventOb.target).closest("a").attr("data-section")).show();
}

/*
	Method: displayWishlist
	
	Builds and displays current User's wishlist. Requrires JSON userlist object.
	If the user listed in object is the current user, we can display edit buttons.
	
	@displayData
		boolean @isCurrentUser - the toggle to determine which toolset to display
		String @toolset - the name of the toolset to include (edit, shop)
		Object @list - the javascript object item list: contains information to build rows.
		String @targetTable - where to put this list. 
*/
function displayWishlist(displayData){
	//debug = displayData;
	//The table we're plugging this into.
	table = $("#"+displayData.targetTable);
	
	table.attr("data-listOwner",displayData.forUserId);
		
	/*
	Builds the Table header and puts the columns into a definable order.
	*/
	if(displayData.skipHeader == true){
		jQuery("#"+displayData.targetTable+" tr.itemRow").remove();
		
	}else{
		table.html("");	
		
		hRow = $(document.createElement("tr"));
		
		$(displayData.columns).each(function(i,e){
				var th = $(document.createElement("th")).append(e.columnName)
				if(e.sortFunctions[0] != undefined){
					th.toggle(
						function() {
							e.sortFunctions[0](displayData)
						},
						function(){
							e.sortFunctions[1](displayData)
						}
					)
				}
				hRow.append(th);
				
		});
		
		table.append(hRow);		
	}

	//Loop through each item on the user list and add it to a row, which is then added to the table.

	$(displayData.list).each(function(i,e){
		row = $(document.createElement("tr"))
			.attr("data-itemId",e.itemid)
			.attr("id","item_"+e.itemid+"_row")
			.attr("data-toggle","collapse")
			.attr("data-target","detail"+i)
			.addClass("itemRow");
		
		//Generates any needed display versions of properties. Builds display-specific items depending on toolset value.
		e.toolset = displayData.toolset;
		e = generateDisplayElements(e);
		
		/*
		This loops through our table structure and puts the data in the right order. Allows users
		to change the column order, or add/remove columns if they care to without resorting to the
		code. There will need to be a tool to change column order to make this valuable.
		*/	
		
		for(column in displayData.columns){
			
			colToDisplay = displayData.columns[column].displayColumn;
			colDisplayAlt = displayData.columns[column].displayAlt;
			
			displayVal = e[colToDisplay];
			
			if(displayVal == null || displayVal == undefined){ 
				displayVal = e[colDisplayAlt];
			}			
			
			
			
			var cell =	$(document.createElement("td"))
						.append(displayVal)
						.attr("id","item_"+e.itemid+"_"+displayData.columns[column].columnName)
						.addClass("item_"+displayData.columns[column].columnName);
		
			if(displayData.columns[column].displayStyles != undefined){
				cell.addClass(displayData.columns[column].displayStyles);
			}
			

			if(displayData.columns[column].columnName != "Tools"){
				cell.click(function(){
					getItemDetailInfo(e.itemid);
				});
			}

			row.append(cell);
			
			}
			table.append(row);								
		});	
}

function displayItemsDetails(itemInfo){

	$("#itemDetailName").html(itemInfo.itemid);
	$("#itemDetailComment").html(itemInfo.comment);
	
	$("#itemDetailsModal").modal('show');
}


function login(){

	userVal = jQuery("#username").val();
	passVal = jQuery("#password").val();

	if(userVal == null || userVal.length == 0 || passVal == null || passVal.length == 0){
		$("#alertLocation").append(createAlert("You must enter a username and password","error"));
		return false;
	}

	data = {
		interact:'user',
		action:'loginUser',
		username: userVal, 
		password: passVal
	}
	
	showLoadingIndicator();
	
	jQuery.post('ajaxCalls.php',data,function(response){

		hideLoadingIndicator();

		if(response == "true"){
			window.location.reload();
		}else{
			$("#alertLocation").append(createAlert("Incorrect login.","error"));
		}
	});
}

function logout(){

	data = {
		interact:'user',
		action:'logoutUser'
	}
	
	jQuery.post('ajaxCalls.php',data,function(response){
		if(response){
			window.location.reload();
		}
	});
	
}

function getCurrentUserList(includeReceived){
	data = {
		interact:'wishlist',
		action:'getCurrentUserWishlist',
		args:{'includeReceived':includeReceived}
	}
	showLoadingIndicator()
	jQuery.post('ajaxCalls.php',data,function(response){
		
		storedData.userWishlist = response;
		
		wishlistData = {};
		wishlistData.isCurrentUser = true;
		wishlistData.forUserId = userId;		
		wishlistData.toolset = "edit";		
		wishlistData.list = response;		
		wishlistData.targetTable = "userWishlist";
		wishlistData.skipHeader = false;
		wishlistData.columns = storedData.columns;

		displayWishlist(wishlistData);
		hideLoadingIndicator();		
	},"json");
}


/*
Function: getUserWishlist
	fetches the wishlist of a particular user and displays it in the "otherUserWishlist" table.
	
	@forUserId - The id of the user you would like to get the list for.
*/
function getUserWishlist(forUserId){
	data = {
		interact:'wishlist',
		action:'getShoppingForList',
		args:{shopForId:forUserId}
	}
	showLoadingIndicator();
	jQuery.post('ajaxCalls.php',data,function(response){
		
		if(response.responseType != undefined && response.responseType == "error"){
			errorMessage(response);
			//return false;
		}else{
			userWishlistData = {};
			userWishlistData.isCurrentUser = false;
			userWishlistData.forUserId = forUserId;
			userWishlistData.toolset = "shop";
			userWishlistData.list = response;		
			userWishlistData.skipHeader = false;			
			userWishlistData.targetTable = "otherUserWishlist";
			userWishlistData.columns = storedData.columns2;

			displayWishlist(userWishlistData);
		}		
		hideLoadingIndicator();
	},"json");	
}

/*
Javascript sort functions
*/

function sortByPriceDesc(listObject){
	listObject.list.sort(function(a,b){return a.minprice - b.minprice});
	listObject.skipHeader = true;
	displayWishlist(listObject);
}

function sortByPriceAsc(listObject){
	listObject.list.sort(function(a,b){return b.minprice - a.minprice});
	listObject.skipHeader = true;
	displayWishlist(listObject);	
}


function sortByDescriptionDesc(listObject){
	listObject.list.sort(function(a,b){
			if(a.description > b.description){
				return -1;
			}else if(a.description < b.description) {
				return 1
			}else{
				return 0;
			}
		});
	listObject.skipHeader = true;
	displayWishlist(listObject);

}

function sortByDescriptionAsc(listObject){	
	listObject.list.sort(function(a,b){
		if(a.description > b.description){
			return 1;
		}else if(a.description < b.description) {
			return -1
		}else{
			return 0;
		}
	});
	listObject.skipHeader = true;
	displayWishlist(listObject);
}

function sortByRankingDesc(listObject){	
	listObject.list.sort(function(a,b){return a.ranking - b.ranking});
	listObject.skipHeader = true;
	displayWishlist(listObject);
}

function sortByRankingAsc(listObject){
	listObject.list.sort(function(a,b){return b.ranking - a.ranking});
	listObject.skipHeader = true;
	displayWishlist(listObject);	
}


/*
	Method: generateDisplayElements
	This method takes a data object returned from the database and generates appropriate display data. 
	Returns the object
	If you want to add controls, images, etc to individual list items on the list, this is the place to do it.
	

	object @itemObject - The item returned from the database.
	
*/
function generateDisplayElements(itemObject){

	switch(itemObject.toolset){
		case "shop":
			itemObject.displayToolbox = renderItemTools(itemObject,"shop");

			itemObject.displayDescription = $(document.createElement("div"));		
			itemObject.displayDescription.append($(document.createElement("span")).append(itemObject.description))
			

			if(itemObject.available == null) itemObject.available = itemObject.quantity;
			itemObject.displayStatus = (itemObject.available > 0)? itemObject.available+" Remaining":"None Remaining";
			
			
		break;
		case "edit":
		
			itemObject.displayToolbox = renderItemTools(itemObject,"edit");
			itemObject.displayDescription = $(document.createElement("span")).append(itemObject.description);
		break;
	}
	
	itemObject.displayRanking = renderRanking(itemObject.ranking);

	return itemObject
}



function showMoreInfo(eventObject){
	//infoContainer = jQuery("#itemDetailRow");
	itemRow = jQuery(eventObject.target).closest('tr');
	//itemRow.after(infoContainer);
	
	getItemDetailInfo(itemRow.attr("data-itemid"));
}


/*
	Method: getItemDetailInfo
	This method takes an itemId and fetches detailed information about it: Images, Sources (shops), Reservation info, and Comments.

	int @itemId - the id of the item to be requested.

*/
function getItemDetailInfo(itemId){
	//jQuery(".itemDetailContainer").html("");
	
	data = {
		interact:'wishlist',
		action:'getItemDetails',
		args:{itemid:itemId}
	}
	showLoadingIndicator();
	
	jQuery.post('ajaxCalls.php',data,function(response){
		
		debug = response;
		jQuery('#itemDetailName').html(response.itemDescription);
		jQuery('#itemDetailComment').html(response.itemComment);
		jQuery('#itemDetailRanking').html(renderRanking(response.itemRanking));
		
		
		//Sources Section
		if(response.sources != null && response.sources != undefined){
			jQuery("#itemDetailSourcesTable").html("");
		
			jQuery(response.sources).each(function(i,e){
			sourceRow = jQuery(document.createElement('tr'));
			sourceNameCell = jQuery(document.createElement('td'));
			sourcePriceCell = jQuery(document.createElement('td'));
			
			//Add a url source or just the sourcename.
			if(e.itemSourceUrl != null){ 
				sourceName = jQuery(document.createElement('a'))
								.attr('href',e.itemSourceUrl)
								.attr("target","_blank")
								.append(e.itemSource);
			}else{
				sourceName = e.itemSource;
			}
			
			sourceNameCell.append(sourceName);
			sourcePriceCell.append(e.itemSourcePrice);
			
			sourceRow.append(sourceNameCell)
					.append(sourcePriceCell);
			
			jQuery("#itemDetailSourcesTable").append(sourceRow);
		});
		
		}else{
			jQuery('#itemDetailSourcesTable').html("No Stores/Shops have been provided for this item.");
		}

		//Images Section
		if(response.images != undefined && response.images != null){
			
			//Clears out previous carousel items
			jQuery('#itemDetailImageCarousel div.carousel-inner').empty();
			
			//Generates carousel images & containers.
			jQuery(response.images).each(function(i,e){
				img = $(document.createElement('img')).attr('src',"uploads/"+e.itemImageFilename);
				itemImageDiv = $(document.createElement('div')).addClass("item").append(img);
				if(i == 0)itemImageDiv.addClass("active");
				jQuery('#itemDetailImageCarousel div.carousel-inner').append(itemImageDiv);
			});
			
			//Starts the carousel.
			jQuery('#itemDetailImageCarousel').carousel();
			
		}else{
			jQuery('#itemDetailImageCarousel div.carousel-inner').html("No images have been provided for this item.");
		}
		
		//Alloc Section
		allocElement = jQuery(document.createElement("div"));
		
		
		if(response.allocs != null &&  response.allocs != "currentUser"){
			jQuery(response.allocs).each(function(i,e){
				message = e.itemAllocUserName+" has reserved "+e.itemAllocQuantity+" of this item";
				allocElement.append($(document.createElement('div')).html(message));				
			});
		}else if(response.allocs == null){
		    allocElement.html("This item has not be reserved yet.");
		}

		jQuery("#itemDetailAlloc").html(allocElement);
		
		$("#itemDetailsModal").modal();
		
		hideLoadingIndicator();
	},"json");	
	
}


/*
Function: renderRanking
	Currently takes an integer and turns it into a series of asterisks. In the future this should render an 
	image.
	
	int @rankValue - The ranking of an item as a number.
*/
function renderRanking(rankValue){
	var rankReturn = $(document.createElement('div')).addClass('rank');
	var myClass = "";
	
	switch(rankValue){
		case "1":
			myClass = "one";
		break;
		case "2":
			myClass = "two";		
		break;
		case "3":
			myClass = "three";		
		break;
		case "4":
			myClass = "four";		
		break;
		case "5":
			myClass = "five";
		break;
		default:
			console.log(typeof rankValue);
		break;								
	}
	
	rankReturn.addClass(myClass);
	return rankReturn;
}

/*

-----DEPRECATED! RenderCategory is currently doing nothing!-------------

Function renderCategory
	Takes a category id and returns the category display name. Fetches the category set and populates the storedData.categories object if it's empty.
	
	int @categoryId - the id (interger) of the category
*/
/*
function renderCategory(categoryId){
	if(storedData.categories.length == 0){
		console.log("preparing to request data");
		data = {
			interact:'wishlist',
			action:'getCategories'
		}
		jQuery.post('ajaxCalls.php',data,function(response){
			storedData.categories = response;
			return storedData.categories[categoryId];
		},"json");
	}else{
		console.log("data is local");
	}
}
*/

/*
Function renderItemTools
	Produces HTML buttons/icons for interacting with the item in the row.
	
	JS Object @itemObject - A Javascript object returned from the wishlist system.
	JS Object @toolInfo - A Javscript object with owner,  
*/
function renderItemTools(itemObject, toolInfo){
	
	toolBox = $(document.createElement("div"));
	
	switch(toolInfo){
		
		case "edit":		
			itemDelete = $(document.createElement("i"))
							.addClass("icon-trash tool")
							.attr("title","Delete Item");
							
			itemReceive = $(document.createElement("i"))
							.addClass("icon-gift tool")
							.attr("title","Mark Item Received");
							
			itemEdit = $(document.createElement("i"))
							.addClass("icon-pencil tool")
							.attr("title","Edit Item");
			
			//data-itemId is stored on the row element: tool->div->td->tr

			itemReceive.click(function(){
				markItemReceived($(this).closest("tr").attr("data-itemId"));
				/*
				alert("Marked Received: "+
				$(this).closest("tr").attr("data-itemId"))
				*/
			});

			itemEdit.click(function(){
				populateManageItemForm($(this).closest("tr").attr("data-itemId"));
				$("#openAddImageForm").removeClass("disabled").prop("disabled","");
			});

			itemDelete.click(function(){
				deleteItem($(this).closest("tr").attr("data-itemId"));
			});

			toolBox.append(itemReceive);
			toolBox.append(itemEdit);
			toolBox.append(itemDelete);				
		break;
		case "shop":

			//Reserve
			if(itemObject.available > 0 ){	
				itemReserve = $(document.createElement("i"))
						.addClass("icon-lock tool")
						.attr("title","Reserve Item")
						.click(function(){
							allocateHandler($(this).closest("tr").attr("data-itemId"),userId,"reserve", $(this).closest("table").attr("data-listOwner"));
						});
				toolBox.append(itemReserve);
			}
		
			if(itemObject.reservedByThisUser > itemObject.boughtByThisUser){
				//Release
				itemRelease = $(document.createElement("i"))
						.addClass("icon-hand-left tool")
						.attr("title","Release Item")
						.click(function(){
							allocateHandler($(this).closest("tr").attr("data-itemId"),userId,"release", $(this).closest("table").attr("data-listOwner"));
						});
				toolBox.append(itemRelease);

				//Purchase
				itemBuy = $(document.createElement("i"))
						.addClass("icon-shopping-cart tool")
						.attr("title","Buy Item")
						.click(function(){
							allocateHandler($(this).closest("tr").attr("data-itemId"),userId,"purchase", $(this).closest("table").attr("data-listOwner"));
						});
				toolBox.append(itemBuy);
			}
			
			//Return
			if(itemObject.boughtByThisUser > 0){
				itemReturn = $(document.createElement("i"))
						.addClass("icon-share tool")
						.attr("title","Buy Item")
						.click(function(){
							allocateHandler($(this).closest("tr").attr("data-itemId"),userId,"return", $(this).closest("table").attr("data-listOwner"));
						});
				toolBox.append(itemReturn);
			}
			

			//There are no limitations on copying an item. 
			itemCopy = $(document.createElement("i"))
					.addClass("icon-tags tool")
					.attr("title","Copy Item")
					.click(function(){
						alert("Copy ItemId "+$(this).closest("tr").attr("data-itemId")+" - not implemented yet.");
						//this.parentNode.parentNode.parentNode.getAttribute("data-itemId");
					});
			toolBox.append(itemCopy);

		break;
		case "sourceEdit":
		
			sourceDelete = $(document.createElement("i"))
							.addClass("icon-trash tool")
							.attr("title","Delete Source");
						
			sourceEdit = $(document.createElement("i"))
							.addClass("icon-pencil tool")
							.attr("title","Edit Source");

			sourceEdit.click(function(){
				populateItemSourceForm($(this).closest("tr").attr("data-itemSourceId"));
			});

			sourceDelete.click(function(){
				deleteItemSource(
					$("input#itemId").val(),
					$(this).closest("tr").attr("data-itemSourceId")
				);
			});

			toolBox.append(sourceEdit);
			toolBox.append(sourceDelete);							
		
		break;		
	}
	
	return toolBox;
	
}

/*
Function buildShopForSet
	Builds a set of html option elements and places them in shop for list on the "Other's lists" tab and the "I'm shopping for" list on the "manage" tab.
*/

function buildShopForSet(){
	data = {
		interact:'user',
		action:'getShopForUsers'
	}
	
	jQuery.post('ajaxCalls.php',data,function(response){
		listOfUsersTable = $("#listOfUsersTable");
		shopForTable = $("#currentShopFor");
		
		shopForTable.empty();
		
		$(response).each(function(i,e){
			shopForRow = $(document.createElement("tr"));
			shopForCell = $(document.createElement("td"))
							.html(e.fullname)
							.attr("data-userid",e.userid);
			if(e.pending == 1){
				shoppingForState = $(document.createElement('span')).html("Pending").addClass("label label-warning cellInfo");

			}else{
				shoppingForState = $(document.createElement('button')).html("Remove")
							.addClass("btn btn-mini btn-danger cellInfo")
							.click(function(){
								removeShoppingFor($(this).closest('td').attr("data-userid"));
							});				
			}
			shopForCell.append(shoppingForState);
			
						
			shopForRow.append(shopForCell);
			shopForTable.append(shopForRow);			



			if(e.pending == 0){
				userRow = $(document.createElement("tr"));
				nameCell = $(document.createElement("td"))
							.html(e.fullname)
							.attr("data-userid",e.userid)
							.attr("id","listRowUser-"+e.userid);
			
				//I was using the extend method of jQuery here to simply duplicate the object
				//but it was causing problems in terms of one table or the other.


				nameCell.click(function(e){
				
					getUserWishlist($(e.target).attr("data-userid"));

					//Sets the request to fire the slideshow transition onclick.
					$("#myCarousel").carousel('next');
				});
			
				userRow.append(nameCell);			
				listOfUsersTable.append(userRow);
			}
		});
		
		
		$("#listOfUsers").change(function(e){
				getUserWishlist(this.value);
			});
		
	},"json");
}


/*
	Method: buildCategorySelect
		Builds option elements with category names and their ids as values. Appends them to the second argument Element.
		
		array @categoryObject - a javascript array of objects that contain category names and ids.
		string @parentElement - the element where these items should be appened to.
*/
function buildCategorySelect(categoryObject,parentElement){

	//Set these to defaults if they're not defined in the call
	//I don't think these are necessary any longer because this is no longer generated on the fly.
	
//	categoryObject = (categoryObject == undefined)? storedData.categories: categoryObject;
//	parentElement = (parentElement == undefined)?".categorySelect": parentElement;

	jQuery(categoryObject).each(function(i,e){
		var option =  jQuery(document.createElement("option"))
							.attr("value",e.categoryid)
							.html(e.category);
		jQuery(parentElement).append(option);
	});
		
}


/*
	Method: buildRankSelect
		Builds option elements with Rank display, Appends them to the second argument Element. Depends on renderRanking

		array @rankObject - a javascript array of objects that contain category names and ids.
		string @parentElement - the element where these items should be appened to.
*/
function buildRankSelect(rankCount,parentElement){
	var rankOptionsList = "";

	for(var i = 1; i <= rankCount; i++){
	        var rankOption = '<option value="'+i+'">'+i+'</option>';
	        jQuery(parentElement).append(rankOption);
	}

}



/*
	Method: deleteItem
		Deletes an item from the user's wishlist
		
		int @itemId - The id of the item to delete.
*/
function deleteItem(itemId){
	
	data = {
		interact:'wishlist',
		action:'manageItem',
		args:{
			itemAction:'delete',				
			itemid:itemId
		}
	}
	
	//Get the Categories.
	jQuery.post('ajaxCalls.php',data,function(response){
		if(response){
			getCurrentUserList(listReceived);
		}
		
	});
}

/*
	Method: markItemReceived
		Marks an item as received
		
		int @itemId - The id of the item to delete.
*/
function markItemReceived(itemId){
	
	data = {
		interact:'wishlist',
		action:'markItemReceived',
		args:{
			itemid:itemId
		}
	}
	
	//Get the Categories.
	jQuery.post('ajaxCalls.php',data,function(response){
		if(response){
			getCurrentUserList(listReceived);
		}
		
	});
}



/*	Method: manageItem
	Takes data from manageItemForm and sends it to the database via AJAX
				
*/
function manageItem(){
	
	data = {
		interact:'wishlist',
		action:'manageItem',
		args:{}
	}
	currentItemId = jQuery("#manageItemForm #itemId").val();
	
	//Ternary operation to determine whether we're editing or adding an item.
	data.args.itemAction = (currentItemId == "") ? "add" : "edit";
	
	data.args.itemid = currentItemId;
	data.args.description = jQuery("#itemDescriptionInput").val();
	data.args.category = jQuery("#itemCategoryInput").val();
	data.args.quantity = jQuery("#itemQuantityInput").val();
	data.args.comment = jQuery("#itemCommentInput").val();
	data.args.ranking = jQuery("#itemRankInput").val();
	
	jQuery.post('ajaxCalls.php',data,function(response){
		
		getCurrentUserList(listReceived);
		$("#manageItemFormBlock").modal('hide');
	});	
}

/* Method: clearManageItemForm
	Clears unique inputs on manageItemForm
	
*/
function clearManageItemForm(){
	jQuery('#itemId').val("");
	jQuery('#itemDescriptionInput').val("");
	jQuery('#itemQuantityInput').val("");
	jQuery('#itemRankInput').val("1");
	jQuery('#itemCategoryInput').val("1");
	jQuery('#itemSourcesEdit').html("");
	jQuery('#itemCommentInput').val("");	
	jQuery('#openAddImageForm').attr("data-forItemId","");	
	
	//console.log("form cleared");
}

/* Method: populateManageItemForm
	Gets the itemDetails and puts them into the #manageItemForm form, then calls the modal to display.
*/
function populateManageItemForm(itemId){
	
	clearManageItemForm(); //Clears the form of any previous data. 
	
	data = {
		interact:'wishlist',
		action:'getItemDetails',
		args:{itemid:itemId}
	}
	showLoadingIndicator();

	jQuery.post('ajaxCalls.php',data,function(response){
		debug = response;
		
		jQuery('#itemId').val(itemId);
		jQuery('#itemDescriptionInput').val(response.itemDescription);
		jQuery('#itemQuantityInput').val(response.itemQuantity);
		jQuery('#itemRankInput').val(response.itemRanking);
		jQuery('#itemCategoryInput').val(response.itemCategory);
		jQuery('#itemCommentInput').val(response.itemComment);		
		jQuery('#openAddImageForm').attr("data-forItemId",itemId);
		
		//Sources Data
		if(response.sources != undefined){
			jQuery(response.sources).each(function(i,e){
				
				sourceCell = jQuery(document.createElement('td'))
								.html(e.itemSource);

				
				sourceEditTools = jQuery(document.createElement('td'))
										.append(renderItemTools(e.itemSource,"sourceEdit"));
									
								
				sourceOption = jQuery(document.createElement('tr'))
									.append(sourceCell)
									.append(sourceEditTools)
									.attr("data-itemSourceId",e.itemSourceId);
		
				jQuery("#itemSourcesEdit").append(sourceOption);
			});
		
		}		
		
		var addSourceButton = jQuery(document.createElement('button'))
								.addClass("btn btn-primary btn-mini tool")
								.append("Add Source")
								.click(function(){
									clearItemSourceForm();
									$("#itemSourceFormBlock #itemId").val(itemId);
									$("#manageItemFormBlock").modal("hide");
									$("#itemSourceFormBlock").modal("show");
									//swapModal("#itemSourceFormBlock")
								});
								
		var addSourceCell = jQuery(document.createElement('td')).attr("colspan","2").append(addSourceButton);
		var addSourceRow = jQuery(document.createElement('tr')).append(addSourceCell);

		jQuery("#itemSourcesEdit").append(addSourceRow);
		
		
		
		$('#manageItemFormBlock').modal('show');
		hideLoadingIndicator();
	},"json");
}

/* Method clearItemSourceForm
	Clears the values in the Item Source Form
*/
function clearItemSourceForm(){
	
	$("#itemSourceForm #itemId").val("");
	$("#itemSourceForm #sourceId").val("");
	$("#itemSourceForm #sourceName").val("");
	$("#itemSourceForm #sourceUrl").val("");
	$("#itemSourceForm #sourcePrice").val("");
	$("#itemSourceForm #sourceComments").val("");
	
}



/* Method populateItemSourceForm
	Gets itemSource details and puts them into the #itemSourceForm form, then calls teh modal to display.
*/
function populateItemSourceForm(sourceId){
	// Note to developer: This should probably also get the name of the related item, so it's available to the user for context.
	data = {
		interact:'wishlist',
		action:'getSourceDetails',
		args:{'sourceId':sourceId}
	}
	
	jQuery.post('ajaxCalls.php',data,function(response){
		$("#itemSourceForm #itemId").val(response.itemid);
		$("#itemSourceForm #sourceId").val(response.sourceid);
		$("#itemSourceForm #sourceName").val(response.source);
		$("#itemSourceForm #sourceUrl").val(response.sourceurl);
		$("#itemSourceForm #sourcePrice").val(response.sourceprice);
		$("#itemSourceForm #sourceComments").val(response.sourcecomments);										
		
		$('#manageItemFormBlock').modal('hide');
		$("#itemSourceFormBlock").modal("show");
	
	},"json");	
}



/* Method: manageItemSource
	Adds or Updates an item source.

*/
function manageItemSource(){
	
	args = {};
	
	args.itemid = $("#itemSourceForm #itemId").val();
	args.sourceid = $("#itemSourceForm #sourceId").val();
	args.source = $("#itemSourceForm #sourceName").val();
	args.sourceurl = $("#itemSourceForm #sourceUrl").val();
	args.sourceprice = $("#itemSourceForm #sourcePrice").val();
	args.sourcecomments = $("#itemSourceForm #sourceComments").val();
	args.itemSourceAction = (args.sourceid.length == 0)?"add":"edit";

	data = {
		interact:'wishlist',
		action:'manageItemSource',
		"args":args
	}
	
	jQuery.post('ajaxCalls.php',data,function(response){
		if(response){
			getCurrentUserList(listReceived);
		}
	},"json");
	
}


/* Method: deleteItemSource
	removes a source from an item
*/
function deleteItemSource(itemId,sourceId){
	data = {
		interact:'wishlist',
		action:'manageItemSource',
		args:{'sourceid':sourceId,
			'itemSourceAction':'delete'}
	}
	
	jQuery.post('ajaxCalls.php',data,function(response){
		populateManageItemForm(itemId);
	});	
}


function populateImagesOnForm(itemId){
	data = {
		interact:'wishlist',
		action:'getImages',
		args:{"itemId":itemId}
	}
	jQuery.post('ajaxCalls.php',data,function(response){
		$("#currentImagesBlock").empty();
		
		$(response).each(function(i,e){
			var img = $(document.createElement('img')).attr('src',"uploads/"+e.filename);
			var itemImageDiv = $(document.createElement('div')).append(img).addClass("imageBlock");
			var removeImageControl =  $(document.createElement('a')).append("×").addClass("close").click(function(){
				
				remove = {
					interact:'wishlist',
					action:'manageItemImage',
					args:{
						"imageid":e.imageid,
						"itemImageAction":"delete"
					}
				}
				jQuery.post('ajaxCalls.php',remove,function(response){
					$(this.parent).remove();
					//This seems recursive, but it's really just setting up the call to refresh the images on the form here.
					populateImagesOnForm(itemId); 
				});
			});
			
			itemImageDiv.append(removeImageControl);
			$("#currentImagesBlock").append(itemImageDiv);
		});

	},"json");
}

/*
	Method populateManageUserForm
		Populates the Manage User Form.
*/
function populateManageUserForm(userId){
	data = {
		interact:'user',
		action:'getUser',
		args:{"userid":userId}
	}
	showLoadingIndicator();
	jQuery.post('ajaxCalls.php',data,function(response){
		
		
		$("#manageUser input#userId").val(userId);
		$("#username").val(response.username);
		$("#userFullName").val(response.fullname);
		$("#emailAddress").val(response.email);

		//Any time we're populating this form, we're going to be editing, so we can put this in the function call.
		$("#manageUser input#userAction").val("edit"); 

		//We need some logic for these when the logged in user is not an Admin, and these elements don't exist.
		var userApproved = (response.approved == 1)?true:false;
		var userAdmin = (response.admin == 1)?true:false;
		
		$("#userApproved").prop("checked",userApproved);
		$("#userIsAdmin").prop("checked",userAdmin);
		
		$("#userFormBlock").modal();
		
		hideLoadingIndicator();
		
	},"json");
	
}

/*
	Method updateUserData
		Updates 
*/
function updateUserData(){
	args = {};
	data = {
		interact:'user',
		action:'manageUser'
	}

	fields = {
		"username":"#manageUser #username",
		"fullname":"#manageUser #userFullName",
		"email":"#manageUser #emailAddress",
	}
	
	for(fieldName in fields){
		args[fieldName] = $(fields[fieldName]).val();
	}
	
	var approvedCheck = $("#manageUser #userApproved:checked");
	var adminCheck = $("#manageUser #userIsAdmin:checked");

	for(field in args){
		if(args[field].length == 0){
			//If the field has a length 0, we set the help text, and attach the error class to the parent control-group
			$(fields[field]).next(".help-inline").append("Field must not be empty")
							.closest(".control-group").addClass("error");
			return false;	
		}
	}
	
	if(approvedCheck != undefined && approvedCheck.length > 0){
		args.approved = 1;
	}
	
	if(adminCheck != undefined && adminCheck.length > 0){
		args.admin = 1;
	}
		
	var pass = $("#manageUser #userPassword").val();
	var confirmPass = $("#manageUser #userPasswordConfirm").val();

	if(confirmPass == pass){
		args.password = pass;
	}else{
		$("#manageUser .passwordSet").closest(".control-group").addClass("error");
		$("#userPassword").next(".help-inline").append("Both password fields must match");
		
		// This will set the interface to remove the error class and warning on clicking the field.
		$("#manageUser .passwordSet").click(function(){
			$("#manageUser .passwordSet")
				.unbind("click")
				.next(".help-inline")
					.html("")
				.closest(".control-group")
					.removeClass("error");
		});
		return false;
	}
	args.userId = $("#manageUser #userId").val();
	args.userAction =$("#manageUser #userAction").val();
	
	
	//If we've made it this far, we're packaging up and sending off!
	data.args = args;	
	jQuery.post('ajaxCalls.php',data,function(response){
		$("#userFormBlock").modal("hide");
	});	
	
}



/*
	method deleteUserFromSystem

*/
function deleteUserFromSystem(userId){
	data = {
		interact:"user",
		action:'manageUser',
		args:{"userAction":"delete","userId":userId}
		
	}
	jQuery.post('ajaxCalls.php',data,function(response){
		$("#deleteConfirmBlock").modal('hide');
		displaySystemUsers();
	});
}


/*
	Method displaySystemUsers
		Gets a list of users in the system. Only works for Admins.
*/
function displaySystemUsers(){
	data = {
		interact:'user',
		action:'getListOfUsers'
	}
	
	jQuery.post('ajaxCalls.php',data,function(response){
		
		var userListTable = $("table#adminUserList");
		userListTable.empty();
		for(user in response){
			
			var row = $(document.createElement("tr")).attr("data-userId",response[user].userid);
			var name = $(document.createElement("td")).append(response[user].fullname);
			var userName = $(document.createElement("td")).append(response[user].username);
			var email = $(document.createElement("td")).append(response[user].email);
			
			//We should probably expand on tool construction above - but barring that here are some quick tools for management.
			var editUserButton = $(document.createElement("button"))
									.addClass("btn btn-info btn-mini")
									.append("Edit user")
									.click(function(){
										
										populateManageUserForm($(this).closest("tr").attr("data-userId"));
									});
									
			var deleteUserButton = $(document.createElement("button"))
										.addClass("btn btn-danger btn-mini")
										.append("Delete user")
										.click(function(){
											//Set the form delete ID to the userId provided and show the warning Modal.
											$("#deleteObjectForm #deleteObjectId").val($(this).closest("tr").attr("data-userId"))
											$("#deleteConfirmBlock").modal('show');
										});
									
									
									
			
			var userTools = $(document.createElement("td")).append();
			userTools.append(editUserButton)
					.append(deleteUserButton);
			
			row.append(name)
				.append(userName)
				.append(email)
				.append(userTools);
			
			userListTable.append(row);
		}
	},"json");
	
}

/*
	Method allocateHandler
		manages calls to allocating Methods on backend.
*/
function allocateHandler(itemId,userId,action,forUserId){
	
	arguments = {
		"userid":userId,
		"itemid":itemId,
		"allocateAction":action,
		"adjustment":1
	}
	
	data = {
		interact:'wishlist',
		action:'adjustReservedItem',
		"args":arguments
	}
	
	jQuery.post('ajaxCalls.php',data,function(response){
		getUserWishlist(forUserId);
	});
}


/*
	Method setupUserSearch
		Gets all users, associated IDs, sets up array for searching and sets up user search field.
		
*/
function setupUserSearch(){
	data = {
		interact:'user',
		action:'getListOfUsers'
	}
	
	jQuery.post('ajaxCalls.php',data,function(response){
		storedData.userlist = response;
		
		$('#shopForSearch').typeahead({
			source:storedData.userlist,
		    onselect: function(obj){
				//requestToShopFor(userId,obj.userid)
				$("input#userToRequest").val(obj.userid);
			},
			property:'fullname'
		});		
	},"json");	
}




/*
	Method requestToShopFor
		Requests that a user may shop for the current user.
		
		@userid - The userId of the user making the request
		@shopForId - The user to be shopped for.
*/
function requestToShopFor(userId,shopForId){
	data = {
		interact:'user',
		action:'requestShopForUser',
		args:{'shopperId':userId,
			'shopForUserId':shopForId
		}
	}
	showLoadingIndicator();
	jQuery.post('ajaxCalls.php',data,function(response){	
		hideLoadingIndicator();
		buildShopForSet();
	},"json");
}

/*
	Method removeShoppingFor
		Removes a user from your 'shopping for' set.
*/
function removeShoppingFor(shopForId){
	//	$(this).closest('td').attr("data-userid")
	data = {
		interact:'user',
		action:'removeShopForUser',
		args:{'shopperId':userId,
			'shopForUserId':shopForId
		}
	}
	jQuery.post('ajaxCalls.php',data,function(response){	
		buildShopForSet();
	},"json");
	
}



/*
	Method approveShopper
		Approves a shopper's request to shop for you
*/
function approveShopper(shopperId){

	data = {
		interact:'user',
		action:'approveShopForUser',
		args:{'shopForId':userId,
			'shopperId':shopperId
		}
	}
	jQuery.post('ajaxCalls.php',data,function(response){	
		displayShopForMeList();
	},"json");
}

/*
	Method approveShopper
		Approves a shopper's request to shop for you
*/
function disapproveShopper(shopperId){

	data = {
		interact:'user',
		action:'disapproveShopForUser',
		args:{'shopForId':userId,
			'shopperId':shopperId
		}
	}
	jQuery.post('ajaxCalls.php',data,function(response){	
		displayShopForMeList();
	},"json");
}


/*
	Method displayShopForMeList
	Displays the list of users shopping for current user in the manage panel.
	
*/
function displayShopForMeList(){
	data = {
		interact:'user',
		action:'getUsersShoppingFor'
	}
	jQuery.post('ajaxCalls.php',data,function(response){	

		shopForMeTable = $("#shoppingForMe");
		shopForMeTable.empty();

		$(response).each(function(i,e){
			shopForMeRow = $(document.createElement("tr"));
			shopForMeCell = $(document.createElement("td"))
							.html(e.fullname)
							.attr("data-userid",e.userid);
	
				actionButton = $(document.createElement("button")).addClass("btn btn-mini cellInfo");
	
			if(e.pending == 1){
				actionButton.html("Approve")
							.addClass("btn btn-mini btn-info cellInfo")
							.click(function(){
								approveShopper($(this).closest('td').attr("data-userid"));
							});
			}else{
				actionButton.html("Remove")
							.addClass("btn-danger")
							.click(function(){
								disapproveShopper($(this).closest('td').attr("data-userid"));
							});
			}

			shopForMeCell.append(actionButton);			
			shopForMeRow.append(shopForMeCell);
			shopForMeTable.append(shopForMeRow);	
		});

	},"json");	
}

/*
	Method getMessagesForUser
	Gets a list of messages for the given user and displays them in the 
		@userId - The ID of the user
	
*/
function getMessagesForUser(userId,readStatus){
	data = {
		interact:'user',
		action:'getMessages',
		args:{
			"userid":userId,
			"readStatus":readStatus
		}
	}
	jQuery.post('ajaxCalls.php',data,function(response){	
		table = $("#userMessages");
		table.empty();
		
		if(response != null){
			//Adds a message count to the tab control - there are issues with clicking on the badge itself, so holding off for now.
			/*
			messageCount = $(document.createElement("span")).attr("id","messageIcon").addClass("badge badge-important").append('<i class="icon-envelope icon-white"></i>');
			$("#manageTab").append("&nbsp;").append(messageCount);
			*/
			
			$(response).each(function(i,e){
			
				messageRow = $(document.createElement('tr'));
				messageCell = $(document.createElement('td'));
				trimmedMessage = e.message.substring(0,40);
				fullMessage = $(document.createElement('span'))
								.attr("id","message_"+e.messageid)
								.addClass("fullMessage")
								.append(e.message);
			
				messageCell.append(trimmedMessage+"...");
				messageCell.append(fullMessage);
				messageRow.append(messageCell);
				messageCell.click(function(ev){
					displayMessage($(this).children("span.fullMessage").html());
					markMessageRead(e.messageid);
				});

				table.append(messageRow);
			})
			$("#messageIndicator").show();
		}else{
			messageRow = $(document.createElement('tr'));
			messageCell = $(document.createElement('td')).append("No messages at this time");
			messageRow.append(messageCell);
			table.append(messageRow);	
			$("#messageIndicator").hide();
		}
	},"json");
}

/*
	Method displayMessage
	Displays a message from a message list in a modal.
	
	@messageBody - The body of the message you'd like displayed.
*/
function displayMessage(messageBody){
	$("#message div.modal-body").html(messageBody);
	$("#message").modal('show');	
}
/*
	Method markMessageRead
	Sets a message's status to read. Affects how it will be displayed in interface.
*/
function markMessageRead(messageId){
	data = {
		interact:'user',
		action:'markMessageRead',
		args:{
			"messageId":messageId
		}
	}
	jQuery.post('ajaxCalls.php',data,function(response){
		getMessagesForUser(userId,0);
	},"json");
}


/*
	Method swapModal
	Swaps the current modal for the next or the previous. Previous modal is held in a global variable.

	string @modal - optional, provides the jQuery-compatible-selector modal you'd like to go to. If left blank, will take you back to the previous modal.

*/
function swapModal(modal){
	if(modal != undefined){
			
		if(storedData.modalTree.length > 0){
			$(storedData.modalTree[storedData.modalTree.length-1]).modal('hide');
		}
		$(modal).modal("show");
		storedData.modalTree.push(modal);
	}else{
		$(storedData.modalTree.pop()).modal('hide');

		if(storedData.modalTree.length > 0){
			$(storedData.modalTree[storedData.modalTree.length-1]).modal('show');
		}
	}
}






